﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Microsoft.Forums.OfflineStore;
using System.Collections.ObjectModel;
using System.Data.Linq;
using Threading = System.Threading;
using System.Windows.Threading;
using Microsoft.Forums.SyncService;
using System.IO;
using System.Windows.Data;

namespace Microsoft.Forums.ForumsClient.Models
{
    /// <summary>
    /// A container for a forum that will have its root posts displayed on the UI
    /// This wraps child posts in ObserableCollections
    /// </summary>
    public class ThreadedForumViewModel : HierarchicalPostContainerModel, IFilterableModel, IForumViewModel
    {

        /// <summary>
        /// The forum
        /// </summary>
        Forum forum;

        /// <summary>
        /// The forum for this forum container
        /// </summary>
        public Forum Forum
        {
            get
            {
                return forum;
            }
            private set
            {
                if (forum != value)
                {
                    forum = value;
                    OnPropertyChanged("Forum");
                }
            }
        }

        /// <summary>
        ///  Get the user Filter Settings.
        /// </summary>
        public ThreadFilterSettings FilterSettings
        {
            get;
            private set;
        }


        /// <summary>
        /// Create a forum container for the given forum.
        /// </summary>
        /// <param name="forum">forum to make container for</param>
        /// <param name="dispatcher">Dispatcher from the UI thread</param>
        public ThreadedForumViewModel(Forum forum, Dispatcher dispatcher) : base(dispatcher)
        {
            if (forum == null) throw new ArgumentNullException("forum", "forum must not be null");
            if (dispatcher == null) throw new ArgumentNullException("dispatcher", "dispatcher must not be null");

            Forum = ObjectRegistry.GetForum(forum);

            FilterSettings = new ThreadFilterSettings();
            Forum.ThreadAdded += new Action<Guid>(ForumThreadAdded);
        }



        /// <summary>
        /// Returns a <see cref="System.String"/> that represents this instance.
        /// </summary>
        /// <returns>
        /// A <see cref="System.String"/> that represents this instance.
        /// </returns>
        public override string ToString()
        {
            return Forum.DisplayName;
        }

        #region Private and Protected Methods

        /// <summary>
        /// Gets the root posts.
        /// </summary>
        /// <param name="store">The store.</param>
        /// <returns></returns>
        protected override IEnumerable<Post> GetRootPosts(ForumsOfflineStore store)
        {
            var posts = from p in store.Posts
                        where p.ForumId == Forum.Id && p.ParentId == null
                        orderby p.ThreadModifiedOn descending
                        select p;
            return posts;
        }


        /// <summary>
        /// A new thread has been added to this forum
        /// </summary>
        /// <param name="threadId">The threadId.</param>
        void ForumThreadAdded(Guid threadId)
        {
            if (rootPosts == null)
            {
                // This model hasn't had its posts loaded yet so there is ntohing to add
                return;
            }

            Thread thread = ObjectRegistry.GetThread(Forum.Id, threadId);
            Post rootPost = ObjectRegistry.GetPost(Forum.Id, (Guid)thread.RootPostId);
            lock (rootPosts)
            {
                var postModel = new ThreadedPostViewModel(rootPost, DispatcherUI);
                postModel.ThreadIfRootPost = thread;
                Posts.Add(postModel);
            }
        }
        #endregion

    }
}
